package com.chazaqdev.meatbagsorter

import java.text.SimpleDateFormat
import name.pachler.nio.file.*;

import org.codehaus.groovy.grails.commons.GrailsApplication;
import org.codehaus.groovy.grails.web.servlet.GrailsApplicationAttributes;
import org.grails.plugins.imagetools.*

class MonitorFolderService {
	GrailsApplication grailsApplication
	GrailsApplicationAttributes grailsAttributes
    static transactional = true
	
	int nrAvailableThreads = 20
	
	static {
		System.setProperty("com.sun.media.jai.disableMediaLib", "true");
		}
	
	
	def compressAndSavePhoto(Photo photo, String path, String saveToWhere) {
		File f = new File(path)
		try {
			String filePre = saveToWhere + "/" + photo.id
			InputStream is = new FileInputStream(f)
			
			ResizeImage res = new ResizeImage()
			//Copy original
			FileOutputStream fos = new FileOutputStream(filePre + "_orig.jpeg")
			byte[] b = new byte[f.length()]
			is.read(b)
//			b = res.rotateCorrectly (b)
			fos.write (b)
			fos.close()
			
			
			//Make 600 thumb
			fos = new FileOutputStream(filePre +  "_600.jpeg")
			fos.write(res.resizeImageAsJPG (b, 800))
			fos.close()
			
			//Make 100 thumb
			fos = new FileOutputStream(filePre +  "_100.jpeg")
			fos.write(res.resizeImageAsJPG (b, 100))
			fos.close()
			
			f.delete()
			
			photo.photoIsLocked = false
			System.out.println("+" + photo.id + " \t(\"" + path + "\")" + " in " + saveToWhere)
			
		} catch (Exception e) {
			e.printStackTrace()
		}
	}

	
	def garbleUpFileIntoDB(String path, String saveToWhere, File physicalDir) {
		final Photo photo = new Photo(photoIsLocked: true, savedToFolder: saveToWhere).save()
		--nrAvailableThreads
		if (nrAvailableThreads > 0) {
			runAsync {
				compressAndSavePhoto photo, path, physicalDir.getAbsolutePath()
				photo.save()
				++nrAvailableThreads
			}	
		} else {
			compressAndSavePhoto photo, path, physicalDir.getAbsolutePath()
			photo.save()
			++nrAvailableThreads
		}
		
	}
  public static final String DATE_FORMAT_NOW = "yyyy-MM-dd HH:mm:ss";

  public static String now() {
    Calendar cal = Calendar.getInstance();
    SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
    return sdf.format(cal.getTime());
  }

	def startRunningFileMonitor(MonitorFolder mf, String systemPath) {
		runAsync {
			System.out.println("Monitoring folder " + mf.path)
			WatchService watchService = FileSystems.getDefault().newWatchService()
			Path watchedPath = Paths.get(mf.path);
			WatchKey key = null;
			try {
				key = watchedPath.register(watchService, StandardWatchEventKind.ENTRY_CREATE);
			} catch (UnsupportedOperationException uox){
				System.err.println("file watching not supported!");
				// handle this error here
			}catch (IOException iox){
				System.err.println("I/O errors");
				// handle this error here
			}
			for(;;){
				// take() will block until a file has been created/deleted
				WatchKey signalledKey;
				try {
					signalledKey = watchService.take();
				} catch (InterruptedException ix){
					// we'll ignore being interrupted
					continue;
				} catch (ClosedWatchServiceException cwse){
					// other thread closed watch service
					System.out.println("watch service closed, terminating.");
					break;
				}
				
				String started = now()
			
				// get list of events from key
				List<WatchEvent<?>> list = signalledKey.pollEvents();
			
				// VERY IMPORTANT! call reset() AFTER pollEvents() to allow the
				// key to be reported again by the watch service
				signalledKey.reset();
				String savePath =  systemPath + mf.savePath
				
				File f = new File(savePath)
				if (!f.exists() || !f.isDirectory()) {
					f.mkdir()
				}
			
				// we'll simply print what has happened; real applications
				// will do something more sensible here
				for(WatchEvent e : list){
					String message = "";
					if(e.kind() == StandardWatchEventKind.ENTRY_CREATE){
						Path context = (Path)e.context();
						garbleUpFileIntoDB (mf.path + "/" + context.toString(), mf.savePath, f)
					} else if(e.kind() == StandardWatchEventKind.OVERFLOW){
						message = "OVERFLOW: more changes happened than we could retreive";
					}
					System.out.println(message);
				}
				String ended = now()
				System.out.println("#########\n" + list.size() + " items processed")
				System.out.println("Started @ " + started)
				System.out.println("Ended   @ " + ended)
				System.out.println("Directory " + savePath)
			}
			
		}
	}
	
    def serviceMethod() {

    }
}
